package com.niiwoo.civet.mobile.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.activity.stage.service.prize.ActivityPrizeDubboService;
import com.niiwoo.civet.account.dto.common.BankCardDTO;
import com.niiwoo.civet.account.dto.common.BankTypeDTO;
import com.niiwoo.civet.account.dto.common.WithdrawOrderDTO;
import com.niiwoo.civet.account.dto.request.SubmitWithdrawRequestDTO;
import com.niiwoo.civet.account.dto.request.WithdrawOrderQueryRequest;
import com.niiwoo.civet.account.dto.response.AccountBaseResponse;
import com.niiwoo.civet.account.dto.response.WithdrawOrderResponseDTO;
import com.niiwoo.civet.account.dto.response.WithdrawT0CheckResponse;
import com.niiwoo.civet.account.enums.WithdrawAutoType;
import com.niiwoo.civet.account.enums.WithdrawBusinessTypeEnum;
import com.niiwoo.civet.account.enums.WithdrawOrderStatusEnum;
import com.niiwoo.civet.account.service.AccountDubboService;
import com.niiwoo.civet.account.service.WithdrawDubboService;
import com.niiwoo.civet.account.service.bankcard.BankCardDubboService;
import com.niiwoo.civet.base.enums.ChannelCodeEnum;
import com.niiwoo.civet.mobile.util.R360RedisService;
import com.niiwoo.civet.mobile.vo.common.BankCardVO;
import com.niiwoo.civet.mobile.vo.common.BankTypeVO;
import com.niiwoo.civet.mobile.vo.common.FormVO;
import com.niiwoo.civet.mobile.vo.common.UserAccountVO;
import com.niiwoo.civet.mobile.vo.request.withdraw.*;
import com.niiwoo.civet.mobile.vo.response.withdraw.*;
import com.niiwoo.civet.trade.dto.common.ProjectBorrowerPlanDTO;
import com.niiwoo.civet.trade.dto.common.ProjectBorrowerSummaryDTO;
import com.niiwoo.civet.trade.dto.common.ProjectDTO;
import com.niiwoo.civet.trade.enums.TradeConfigEnum;
import com.niiwoo.civet.trade.service.configure.TradeConfigDubboService;
import com.niiwoo.civet.trade.service.myloan.MyLoanDubboService;
import com.niiwoo.civet.trade.service.project.ProjectDubboService;
import com.niiwoo.civet.user.constants.LoginAccountErrorCode;
import com.niiwoo.civet.user.dto.response.ValidUserForbidResponseDTO;
import com.niiwoo.civet.user.dto.response.organization.OrganizationBaseConfigRespDTO;
import com.niiwoo.civet.user.enums.UserForbidTypeEnum;
import com.niiwoo.civet.user.service.OrganizationDubboService;
import com.niiwoo.civet.user.service.UserForbidDubboService;
import com.niiwoo.tripod.lanmao.component.LanMaoGatewayService;
import com.niiwoo.tripod.lanmao.enums.UserDeviceEnum;
import com.niiwoo.tripod.lanmao.enums.UserRoleEnum;
import com.niiwoo.tripod.lanmao.enums.WithdrawFormEnum;
import com.niiwoo.tripod.lanmao.enums.WithdrawTypeEnum;
import com.niiwoo.tripod.lanmao.request.WithdrawRequest;
import com.niiwoo.tripod.lanmao.response.LanMaoGatewayDTO;
import com.niiwoo.tripod.provider.dto.response.PageResponseDTO;
import com.niiwoo.tripod.provider.exception.BizException;
import com.niiwoo.tripod.web.annotation.AuthIgnore;
import com.niiwoo.tripod.web.vo.PageResponseVO;
import com.niiwoo.tripod.web.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * before 5.1.8：WithdrawController为原源生APP接口
 * 5.1.8：引入机构方H5提现入口，该H5入口兼容集团账户提现（APP用户、卡牛、R360）与机构用户账户提现（机构【鸿特】推荐借款人）
 * WithdrawController为源生APP、H5(APP用户)使用，通过header中token进行授权
 * WithdrawThirdController为第三方用户提现（卡牛、R360、机构推荐借款人）使用，通过request body中的token校验
 */
@RestController
@RequestMapping("/withdraw/third")
@Api(tags = "第三方提现(曾水清v5.1.8)", description = "/withdraw/third")
@Slf4j
@AuthIgnore
public class WithdrawThirdController {
    @Reference(version = "1.0.0")
    private WithdrawDubboService withdrawDubboService;
    @Reference(version = "1.0.0")
    private UserForbidDubboService userForbidDubboService;
    @Reference(version = "1.0.0")
    private MyLoanDubboService myLoanDubboService;
    @Reference(version = "1.0.0")
    private ActivityPrizeDubboService activityPrizeDubboService;
    @Reference(version = "1.0.0")
    private AccountDubboService accountDubboService;
    @Reference(version = "1.0.0")
    private BankCardDubboService bankCardDubboService;
    @Reference(version = "1.0.0")
    private TradeConfigDubboService tradeConfigDubboService;
    @Reference(version = "1.0.0")
    private ProjectDubboService projectDubboService;
    @Reference(version = "1.0.0")
    private OrganizationDubboService organizationDubboService;
    @Autowired
    private LanMaoGatewayService lanMaoGatewayService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private static final BigDecimal minWithdrawAmount = new BigDecimal("100.00");

    /**
     * 通过 token 获取 userId
     *
     * @param token   令牌
     * @param channel 渠道
     * @return
     */
    private String verifyTokenAndGetUserId(String token, int channel) {
        log.info("第三方平台###令牌token={}, 渠道channel={}", token, channel);
        R360RedisService.ThirdPart thirdPart = R360RedisService.ThirdPart.of(channel);
        if (thirdPart == null) {
            log.error("第三方平台###未知channel={}", channel);
            throw new BizException(LoginAccountErrorCode.ACCESS_FORBID);
        }
        return Optional.ofNullable(token)
                .map(t -> {
                    String k = String.format("%s%s", thirdPart.getPrefix(), t);
                    String v = redisTemplate.opsForValue().get(k);
                    log.info("第三方平台###访问###k={}, v={}", k, v);
                    return v;
                })
                .orElseThrow(() -> new BizException(LoginAccountErrorCode.ACCESS_FORBID));
    }

    /**
     * 提现检查
     *
     * @return RespVO
     */
    @PostMapping("/check")
    @ApiOperation("提现检查")
    public Result<WithdrawCheckResponseVO> withdrawCheck(@RequestBody WithdrawThirdAuthRequestVO requestVO) {
        String userId = verifyTokenAndGetUserId(requestVO.getToken(), requestVO.getChannel());

        // 第三方提现仅需考虑行为禁止
        //用户是否被禁止提现
        Boolean forbidWithdraw = Boolean.FALSE;
        ValidUserForbidResponseDTO validUserForbid = userForbidDubboService.queryValidUserForbidInfo(userId, UserForbidTypeEnum.WITHDRAW);
        if (Objects.nonNull(validUserForbid)) {
            forbidWithdraw = Boolean.TRUE;
        }

        //返回
        WithdrawCheckResponseVO responseVO = new WithdrawCheckResponseVO();
        responseVO.setForbidWithdraw(forbidWithdraw);
        responseVO.setForbidWithdrawMsg(validUserForbid == null ? null : validUserForbid.getForbidDesc());
        responseVO.setHasOverdueRepayment(false);
        responseVO.setHasTodayRepayment(false);
        return Result.with(responseVO);
    }

    /**
     * T0提现检查
     *
     * @param requestVO
     * @return
     */
    @PostMapping("/t0EnableCheck")
    @ApiOperation("是否支持T0提现检查")
    public Result<WithdrawT0EnableCheckResponseVO> withdrawT0EnableCheck(@RequestBody @Valid WithdrawT0EnableCheckRequestVO requestVO) {
        String userId = verifyTokenAndGetUserId(requestVO.getThirdAuth().getToken(), requestVO.getThirdAuth().getChannel());
        String pushOrgId = organizationDubboService.getOrgId(requestVO.getThirdAuth().getOrgCode());

        //获取用户账户信息
        UserRoleEnum userRoleEnum = UserRoleEnum.enumOf(requestVO.getAccountUserRole());
        Assert.notNull(userRoleEnum, "账户角色不正确");

        //检查是否支持能T0提现
        WithdrawT0CheckResponse withdrawT0CheckResponse = withdrawDubboService.checkT0EnableWithOrg(userId, pushOrgId, userRoleEnum, requestVO.getAmount());

        //返回结果
        WithdrawT0EnableCheckResponseVO responseVO = new WithdrawT0EnableCheckResponseVO();
        responseVO.setT0Enable(withdrawT0CheckResponse.getT0Enable());
        return Result.with(responseVO);
    }

    /**
     * 普通提现时间校验
     *
     * @return RespVO
     */
    @PostMapping("/commonWithdrawCheck")
    @ApiOperation("普通提现时间校验")
    public Result<CommonWithdrawCheckResponseVO> commonWithdrawCheck(@RequestBody @Valid CommonWithdrawCheckRequestVO requestVO) {
        // 1. 当前时间比对，是否在当日22:50-次日00:10
        // 2. 判断垫资余额是否充足
        // 1-是，2-是，走快速提现
        // 1-是，2-否，走普通提现
        // 1-否， 走普通

        String userId = verifyTokenAndGetUserId(requestVO.getThirdAuth().getToken(), requestVO.getThirdAuth().getChannel());
        String pushOrgId = organizationDubboService.getOrgId(requestVO.getThirdAuth().getOrgCode());

        CommonWithdrawCheckResponseVO response = new CommonWithdrawCheckResponseVO();
        response.setEnable((byte) 1);

        DateTime preLimit = new DateTime();
        preLimit = preLimit.withHourOfDay(22).withMinuteOfHour(50).withSecondOfMinute(0);
        DateTime postLimit = new DateTime();
        postLimit = postLimit.withHourOfDay(0).withMinuteOfHour(10).withSecondOfMinute(0);

        if (preLimit.isBeforeNow() || postLimit.isAfterNow()) {
            //获取用户账户信息
            UserRoleEnum userRoleEnum = UserRoleEnum.enumOf(requestVO.getAccountUserRole());
            Assert.notNull(userRoleEnum, "账户角色不正确");

            WithdrawT0CheckResponse t0Check = withdrawDubboService.checkT0EnableWithOrg(userId, pushOrgId, userRoleEnum, requestVO.getAmount());
            if (t0Check.getT0Enable()) {
                response.setEnable((byte) 0);
            }
        }

        return Result.with(response);
    }

    /**
     * 提现首页查询
     *
     * @return RespVO
     */
    @PostMapping("/index")
    @ApiOperation("提现首页查询")
    public Result<WithdrawIndexResponseVO> withdrawIndex(@RequestBody WithdrawThirdAuthRequestVO requestVO) {
        log.info("合作机构推荐的用户提现，请求参数：{}", JSONObject.toJSONString(requestVO));
        String userId = verifyTokenAndGetUserId(requestVO.getToken(), requestVO.getChannel());
        String pushOrgId = organizationDubboService.getOrgId(requestVO.getOrgCode());

        //用户账户列表
        List<AccountBaseResponse> accountBaseResponseList;
        //计算推荐的提现账户
        UserRoleEnum defaultWithdrawAccountRole;
        //绑定的银行卡信息
        BankCardDTO bankCardDTO;
        if (StringUtils.isBlank(requestVO.getOrgCode())) {
            accountBaseResponseList = accountDubboService.listNiiwooAccountByUserId(userId);
            defaultWithdrawAccountRole = calcDefaultWithdrawAccountRole(userId, accountBaseResponseList);
            bankCardDTO = bankCardDubboService.getUserBankCardInfo(userId);
        } else {
            AccountBaseResponse accountBase = accountDubboService.getOrgAccount(userId, pushOrgId);
            accountBaseResponseList = Collections.singletonList(accountBase);
            defaultWithdrawAccountRole = UserRoleEnum.enumOf(accountBase.getAccountRole());
            bankCardDTO = bankCardDubboService.getUserBankCardByAccountId(accountBase.getAccountId());
        }

        BigDecimal withdrawFeeRate;//提现让手续费率
        BigDecimal fastWithdrawIncreaseFeeRate;//快速提现增收费率
        BigDecimal maxWithdrawFeeAmount;//单次提现封顶手续费
        BigDecimal maxWithdrawAmount;//单次提现最高限额
        if (StringUtils.isBlank(requestVO.getOrgCode())) {
            //查询基础配置信息
            Map<String, String> tradeConfigMap = tradeConfigDubboService.selectTradeConfigByEmuns(Arrays.asList(TradeConfigEnum.WITHDRAWFEE,
                    TradeConfigEnum.FASTWITHFRAWFEEINCREASE, TradeConfigEnum.SINGLEWITHDRAWMAXAMOUNT, TradeConfigEnum.WITHDRAWMAXAMOUNT));
            withdrawFeeRate = new BigDecimal(tradeConfigMap.get(TradeConfigEnum.WITHDRAWFEE.getConfigKey()));
            fastWithdrawIncreaseFeeRate = new BigDecimal(tradeConfigMap.get(TradeConfigEnum.FASTWITHFRAWFEEINCREASE.getConfigKey()));
            maxWithdrawFeeAmount = new BigDecimal(tradeConfigMap.get(TradeConfigEnum.SINGLEWITHDRAWMAXAMOUNT.getConfigKey()));
            maxWithdrawAmount = new BigDecimal(tradeConfigMap.get(TradeConfigEnum.WITHDRAWMAXAMOUNT.getConfigKey()));
        } else {
            OrganizationBaseConfigRespDTO orgConfig = organizationDubboService.selectOrganizationBaseConfigByOrgId(pushOrgId);
            Assert.notNull(orgConfig, "orgCode没有对应的费率配置");
            if(orgConfig.getWithdrawType() == 3) {
                withdrawFeeRate = BigDecimal.ZERO;
                fastWithdrawIncreaseFeeRate = BigDecimal.ZERO;
            }else {
                withdrawFeeRate = orgConfig.getWithdrawRateT1();
                fastWithdrawIncreaseFeeRate = orgConfig.getWithdrawRateT0().subtract(withdrawFeeRate);
            }
            maxWithdrawFeeAmount = orgConfig.getWithdrawMaxFee();
            Map<String, String> tradeConfigMap = tradeConfigDubboService.selectTradeConfigByEmuns(Collections.singletonList(TradeConfigEnum.WITHDRAWMAXAMOUNT));
            maxWithdrawAmount = new BigDecimal(tradeConfigMap.get(TradeConfigEnum.WITHDRAWMAXAMOUNT.getConfigKey()));
        }

        //返回
        WithdrawIndexResponseVO withdrawIndexResponseVO = new WithdrawIndexResponseVO();
        withdrawIndexResponseVO.setAccountList(transToUserAccountVO(accountBaseResponseList));
        withdrawIndexResponseVO.setBankCard(transToBankCardVO(bankCardDTO));
        withdrawIndexResponseVO.setWithdrawFeeRate(withdrawFeeRate);
        withdrawIndexResponseVO.setFastWithdrawIncreaseFeeRate(fastWithdrawIncreaseFeeRate);
        withdrawIndexResponseVO.setMaxWithdrawFeeAmount(maxWithdrawFeeAmount);
        withdrawIndexResponseVO.setMinWithdrawAmount(minWithdrawAmount);
        withdrawIndexResponseVO.setMaxWithdrawAmount(maxWithdrawAmount);
        if (Objects.nonNull(defaultWithdrawAccountRole)) {
            withdrawIndexResponseVO.setDefaultWithdrawAccountRole(defaultWithdrawAccountRole.getValue());
        }
        return Result.with(withdrawIndexResponseVO);
    }

    /**
     * 提交提现申请
     *
     * @return RespVO
     */
    @PostMapping("/submit")
    @ApiOperation("提交提现申请，返回懒猫表单")
    public Result<SubmitWithdrawResponseVO> submitWithdraw(@RequestBody @Valid SubmitWithdrawRequestVO requestVO) {
        String userId = verifyTokenAndGetUserId(requestVO.getThirdAuth().getToken(), requestVO.getThirdAuth().getChannel());

        //生成提现订单
        SubmitWithdrawRequestDTO serviceRequest = new SubmitWithdrawRequestDTO();
        serviceRequest.setAccountId(requestVO.getAccountId());
        serviceRequest.setAmount(requestVO.getAmount());
        serviceRequest.setPrizeId(requestVO.getPrizeId());
        serviceRequest.setUserId(userId);
        serviceRequest.setWithdrawAutoType(WithdrawAutoType.NORMAL);
        serviceRequest.setWithdrawBusinessType(WithdrawBusinessTypeEnum.NORMAL_WITHDRAW);
        serviceRequest.setWithdrawType(WithdrawTypeEnum.enumOf(requestVO.getWithdrawType()));
        // TODO[as]：待修改，应平那边处理
        WithdrawOrderDTO withdrawOrderDTO = withdrawDubboService.submitWithdraw(serviceRequest);

        //调用懒猫组件生成表单（待确认提现无需传递WithdrawType参数）
        WithdrawRequest withdrawRequest = new WithdrawRequest();
        withdrawRequest.setNiiwooRedirectUrl(requestVO.getRedirectUrl());
        withdrawRequest.setUserDevice(UserDeviceEnum.MOBILE);
        withdrawRequest.setWithdrawForm(WithdrawFormEnum.CONFIRMED);
        withdrawRequest.setPlatformUserNo(withdrawOrderDTO.getAccountNo());
        withdrawRequest.setRequestNo(withdrawOrderDTO.getRequestNo());
        withdrawRequest.setExpired(withdrawOrderDTO.getExpired());
        withdrawRequest.setAmount(withdrawOrderDTO.getAmount());
        //佣金传递0上海银行会报错
        if (withdrawOrderDTO.getFee().compareTo(BigDecimal.ZERO) > 0) {
            withdrawRequest.setCommission(withdrawOrderDTO.getFee());
        }

        withdrawRequest.setTimestamp(new Date());

        LanMaoGatewayDTO lanMaoGatewayDTO = lanMaoGatewayService.withdraw(withdrawRequest);
        SubmitWithdrawResponseVO response = new SubmitWithdrawResponseVO();
        FormVO formVO = new FormVO();
        formVO.setAction(lanMaoGatewayDTO.getAction());
        formVO.setParams(lanMaoGatewayDTO.getParams());
        response.setForm(formVO);
        return Result.with(response);
    }

    /**
     * 提现记录列表
     *
     * @return RespVO
     */
    @PostMapping("/listRecord")
    @ApiOperation("提现记录查询")
    public Result<ListWithdrawRecordResponseVO> listWithdrawRecord(@RequestBody WithdrawOrderListRequestVO requestVO) {
        //分页查询提现订单
        log.info("listWithdrawRecord request:{}", JSON.toJSONString(requestVO));
        String userId = verifyTokenAndGetUserId(requestVO.getThirdAuth().getToken(), requestVO.getThirdAuth().getChannel());
        log.info("listWithdrawRecord userId:{}", userId);
        String pushOrgId = organizationDubboService.getOrgId(requestVO.getThirdAuth().getOrgCode());
        log.info("listWithdrawRecord pushOrgId:{}", pushOrgId);

        List<Long> accountIds;
        if (StringUtils.isBlank(requestVO.getThirdAuth().getOrgCode())) {
            accountIds = accountDubboService.listNiiwooAccountByUserId(userId).stream().map(AccountBaseResponse::getAccountId).
                    collect(Collectors.toList());
        } else {
            accountIds = new ArrayList<>();
            AccountBaseResponse accountBaseResponse = accountDubboService.getOrgAccount(userId, pushOrgId);
            if(Objects.nonNull(accountBaseResponse)){
                accountIds.add(accountBaseResponse.getAccountId());
            }
            accountIds.add(-1L);
        }
        log.info("listWithdrawRecord accountIds:{}", JSON.toJSONString(accountIds));

        WithdrawOrderQueryRequest withdrawOrderQueryRequest = new WithdrawOrderQueryRequest();
        withdrawOrderQueryRequest.setUserId(userId);
        withdrawOrderQueryRequest.setAccountIds(accountIds);

        List<WithdrawOrderStatusEnum> statusEnumList = new ArrayList<>();
        if (Objects.isNull(requestVO.getStatus()) || requestVO.getStatus() == 0) {
            statusEnumList.add(WithdrawOrderStatusEnum.PRE_SUBMISSION);
            statusEnumList.add(WithdrawOrderStatusEnum.WAIT_CONFIRM);
            statusEnumList.add(WithdrawOrderStatusEnum.OUTING);
            statusEnumList.add(WithdrawOrderStatusEnum.SUCCESS);
            statusEnumList.add(WithdrawOrderStatusEnum.FAIL);
        } else if (requestVO.getStatus() == 1) {
            statusEnumList.add(WithdrawOrderStatusEnum.SUCCESS);
        } else {
            Assert.isTrue(false, "status参数值不合法");
        }

        withdrawOrderQueryRequest.setStatusEnumList(statusEnumList);
        withdrawOrderQueryRequest.setPageNumber(requestVO.getPageNumber());
        withdrawOrderQueryRequest.setPageSize(requestVO.getPageSize());
        log.info("invoke pageWithdrawOrders request:{}", JSON.toJSONString(withdrawOrderQueryRequest));
        PageResponseDTO<WithdrawOrderResponseDTO> responseDTO = withdrawDubboService.pageWithdrawOrders(withdrawOrderQueryRequest);
        log.debug("invoke pageWithdrawOrders response:{}", JSON.toJSONString(responseDTO));

        List<WithdrawRecordVO> withdrawRecordVOList = responseDTO.getItems().stream().map(e -> {
            WithdrawRecordVO vo = new WithdrawRecordVO();
            vo.setAmount(e.getRealAmount());
            vo.setAccountRole(e.getAccountRole());
            vo.setTime(e.getCreateTime());

            //预提交未收到存管回调的单据作为密码未验证
            if (WithdrawOrderStatusEnum.PRE_SUBMISSION.getCode().equals(e.getStatus())) {
                vo.setStatus(Byte.valueOf("3"));//密码未验证
            }
            //待确认和出款中作为提现处理中
            else if (WithdrawOrderStatusEnum.WAIT_CONFIRM.getCode().equals(e.getStatus())
                    || WithdrawOrderStatusEnum.OUTING.getCode().equals(e.getStatus())) {
                vo.setStatus(Byte.valueOf("0"));
            }
            //提现成功
            else if (WithdrawOrderStatusEnum.SUCCESS.getCode().equals(e.getStatus())) {
                vo.setStatus(Byte.valueOf("1"));
            }
            //提现失败
            else if (WithdrawOrderStatusEnum.FAIL.getCode().equals(e.getStatus())) {
                vo.setStatus(Byte.valueOf("2"));
            }
            return vo;
        }).collect(Collectors.toList());

        PageResponseVO<WithdrawRecordVO> pageVO = new PageResponseVO<>();
        pageVO.setTotalCount(responseDTO.getTotalCount());
        pageVO.setTotalPage(responseDTO.getTotalPage());
        pageVO.setItems(withdrawRecordVOList);

        //统计用户成功提现的总额
        BigDecimal totalAmount;
        if (StringUtils.isBlank(requestVO.getThirdAuth().getOrgCode())) {
            totalAmount = withdrawDubboService.queryUserTotalSuccessAmount(userId);
        } else {
            totalAmount = withdrawDubboService.statSuccessWithdrawAmount(accountIds.get(0));
        }
        log.debug("totalAmount:{}", totalAmount);

        //组装返回结果
        ListWithdrawRecordResponseVO responseVO = new ListWithdrawRecordResponseVO();
        responseVO.setPage(pageVO);
        responseVO.setTotalAmount(totalAmount);
        responseVO.setServerDate(new Date());
        return Result.with(responseVO);
    }

    private List<UserAccountVO> transToUserAccountVO(List<AccountBaseResponse> accountBaseResponseList) {
        List<UserAccountVO> userAccountVOList = new ArrayList<>(accountBaseResponseList.size());
        for (AccountBaseResponse accountBaseResponse : accountBaseResponseList) {
            UserAccountVO userAccountVO = new UserAccountVO();
            userAccountVO.setAccountId(accountBaseResponse.getAccountId());
            userAccountVO.setAccountNo(accountBaseResponse.getAccountNo());
            userAccountVO.setAccountRole(accountBaseResponse.getAccountRole());
            userAccountVO.setAvailableAmount(accountBaseResponse.getAvailableAmount());
            userAccountVO.setActiveAccount(accountBaseResponse.getImportUserActiva());

            userAccountVOList.add(userAccountVO);
        }


        return userAccountVOList;
    }

    private BankCardVO transToBankCardVO(BankCardDTO dto) {
        BankTypeDTO bankTypeDTO = dto.getBankType();
        BankTypeVO bankTypeVO = new BankTypeVO();
        bankTypeVO.setBankTypeId(bankTypeDTO.getBankTypeId());
        bankTypeVO.setBankCode(bankTypeDTO.getBankCode());
        bankTypeVO.setBankName(bankTypeDTO.getBankName());

        BankCardVO vo = new BankCardVO();
        vo.setBankCardId(dto.getBankCardId());
        vo.setBankAccountNo(dto.getBankAccountNo());
        vo.setBankType(bankTypeVO);

        return vo;
    }

    //判断用户当天是否需要还款
    private Boolean hasTodayRepayment(String userId) {
        Boolean hasTodayRepayment = Boolean.FALSE;
        List<ProjectBorrowerPlanDTO> planDTOList = myLoanDubboService.queryMyLoanPlanByToday(userId);
        if (!CollectionUtils.isEmpty(planDTOList)) {
            //排除考拉理财等渠道的项目
            List<ProjectDTO> projectDTOList = planDTOList.stream().map(e -> projectDubboService.selectProjectById(e.getProjectId()))
                    .filter(projectDTO -> !ChannelCodeEnum.KAOLA.getChanelCode().equals(projectDTO.getChannelCode()))
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(projectDTOList)) {
                hasTodayRepayment = Boolean.TRUE;
            }
        }

        return hasTodayRepayment;
    }

    //判断用户是否有逾期未还的贷款
    private Boolean hasOverdueRepayment(String userId) {
        Boolean hasOverdueRepayment = Boolean.FALSE;
        List<ProjectBorrowerSummaryDTO> overdueList = myLoanDubboService.queryMyLoanOverdue(userId);
        if (!CollectionUtils.isEmpty(overdueList)) {
            //排除考拉理财等渠道的项目
            List<ProjectDTO> projectDTOList = overdueList.stream().map(e -> projectDubboService.selectProjectById(e.getProjectId()))
                    .filter(projectDTO -> !ChannelCodeEnum.KAOLA.getChanelCode().equals(projectDTO.getChannelCode()))
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(projectDTOList)) {
                hasOverdueRepayment = Boolean.TRUE;
            }
        }

        return hasOverdueRepayment;
    }

    //判断默认提现账户
    private UserRoleEnum calcDefaultWithdrawAccountRole(String userId, List<AccountBaseResponse> accountBaseResponseList) {
        UserRoleEnum defaultWithdrawAccountRole = null;

        AccountBaseResponse borrowAccount = null;
        AccountBaseResponse investAccount = null;
        for (AccountBaseResponse e : accountBaseResponseList) {
            if (UserRoleEnum.BORROWERS.getValue().equals(e.getAccountRole())) {
                borrowAccount = e;
            } else if (UserRoleEnum.INVESTOR.getValue().equals(e.getAccountRole())) {
                investAccount = e;
            }
        }

        if (Objects.nonNull(borrowAccount) && Objects.nonNull(investAccount)) {
            //比较借款账户与投资账户的余额大小
            BigDecimal borrowAccountBalance = borrowAccount.getAvailableAmount();
            BigDecimal investAccountBalance = investAccount.getAvailableAmount();

            //判断用户当天是否需要还款
            Boolean hasTodayRepayment = this.hasTodayRepayment(userId);
            if (hasTodayRepayment) {
                if (investAccountBalance.compareTo(BigDecimal.ZERO) == 0 && borrowAccountBalance.compareTo(BigDecimal.ZERO) > 0) {
                    //借款账户
                    defaultWithdrawAccountRole = UserRoleEnum.BORROWERS;
                } else {
                    //投资账户
                    defaultWithdrawAccountRole = UserRoleEnum.INVESTOR;
                }
            } else {
                //非还款日且非逾期:逾期的已在withdrawCheck中被拦截了
                if (borrowAccountBalance.compareTo(BigDecimal.ZERO) == 0 && investAccountBalance.compareTo(BigDecimal.ZERO) > 0) {
                    //投资账户
                    defaultWithdrawAccountRole = UserRoleEnum.INVESTOR;
                } else {
                    //借款账户
                    defaultWithdrawAccountRole = UserRoleEnum.BORROWERS;
                }
            }
        }

        return defaultWithdrawAccountRole;
    }
}
